
import bpy
import random
import 全局控制.Node.节点和插座基类.bl_节点基类 as 基类
from 节点.对象操作 import bl_对象变换帧

import engine.initLIB.load_dll as engineLib
import ctypes



engineLib.flexCAPI.f_创建Int32值节点.restype = ctypes.c_bool
engineLib.flexCAPI.f_创建Float32值节点.restype = ctypes.c_bool
engineLib.flexCAPI.f_创建Vec3值节点.restype = ctypes.c_bool
engineLib.flexCAPI.f_创建iVec3值节点.restype = ctypes.c_bool
engineLib.flexCAPI.f_创建Array2D_F32变量节点.restype = ctypes.c_bool


engineLib.flexCAPI.f_创建Curve标量节点.restype = ctypes.c_bool




E_随机类型枚举 = [
	("TYPE_random", "0~1 浮点数", "", 0),
	("TYPE_uniform", "范围浮点数", "", 1),
	("TYPE_randint", "范围整数数", "", 2),
]

def f_变量改变更新输出节点(self, context):
	self.outputs['var'].f_setData(self.m_Value)

class C_单值变量基类(基类.C_SN_基类):
	bl_dname = 'bl_node_value'
	def init(self, context):
		super(C_单值变量基类, self).f_init(context)
	def draw_buttons(self, context, layout):
		layout.prop(self, 'm_Value')
	def f_update(self, 是否向下传递=False, input插座=None):
		#if self.outputs['float'].is_linked == False :
		self.outputs['var'].f_setData( self.m_Value )
		super(C_单值变量基类, self).f_update(是否向下传递)








#nodes["Principled BSDF"].inputs[4].default_value

class C_OPS_NODE_插入帧(bpy.types.Operator):
	bl_idname = 'node.node_var_insert_frame'
	bl_label = '变量值插帧'
	bl_options = {'REGISTER', 'UNDO'}
	m_TreeName = bpy.props.StringProperty()
	m_NodeName = bpy.props.StringProperty()
	def execute(operator, context):
		tree = bpy.data.node_groups[operator.m_TreeName]
		node = tree.nodes[operator.m_NodeName]
		node.f_插入关键帧()
		return {'FINISHED'}











def f_update_变量值改变(self, context):
	Index = self.outputs.find('var')
	if Index >= 0:
		self.outputs['var'].f_setData(float(self.m_Value))
	if context and engineLib.flexCAPI.f_node_是否即时更新节点():
		self.id_data.f_节点数据更新_更新树([self])
		#self.id_data.m_是否需要更新被动节点 = True
	print('value set ------------------------------------ ')




class C_Node_Int变量(基类.C_Node_基类):
	bl_dname = 'bl_node_Int'
	bl_label = 'Int 变量'
	
	m_Value = bpy.props.IntProperty(update=f_update_变量值改变)
	def init(self, context):
		super(C_Node_Int变量, self).f_init(context)
		self.outputs.new('C_Socket_I32', name='var')
		
		self.f_toCPP(self.id_data)

	def f_toCPP(self, tree):
		是否更新 = engineLib.flexCAPI.f_创建Int32值节点(ctypes.c_wchar_p(tree.name), ctypes.c_wchar_p(self.name), self.f_getPyObject(tree));
		if 是否更新 :
			f_update_变量值改变(self, None)

	def draw_buttons(self, context, layout):
		col = layout.row()
		col.prop(self, "m_Value")
		
	def f_插入关键帧(self):
		path = 'nodes['+self.name+'].outputs[1].m_Value'
		bl_对象变换帧.f_数据插帧(self.id_data, path, 'I32变量值', bpy.context.scene.frame_current, self.m_Value, 0)

class C_NODE_MENU_IntVar(bpy.types.Operator):
	bl_idname = 'node.node_var_int'
	bl_label = 'Int 变量'
	bl_options = {'REGISTER', 'UNDO'}

	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_Int变量', use_transform=True)
		return {'FINISHED'}











class C_Node_Float变量(基类.C_Node_基类):
	bl_dname = 'bl_node_Float'
	bl_label = 'Float 变量'
	
	m_Value = bpy.props.FloatProperty(update=f_update_变量值改变)
	def init(self, context):
		super(C_Node_Float变量, self).f_init(context)
		self.outputs.new('C_Socket_F32', name='var')
		self.f_toCPP(self.id_data)

	def f_toCPP(self, tree):
		是否更新 = engineLib.flexCAPI.f_创建Float32值节点(ctypes.c_wchar_p(tree.name), ctypes.c_wchar_p(self.name), self.f_getPyObject(tree));
		if 是否更新 :
			f_update_变量值改变(self, None)

	def draw_buttons(self, context, layout):
		col = layout.column()
		col.prop(self, "m_Value")
		#col.template_curve_mapping(self, "m_Value")
		
	def f_插入关键帧(self):
		path = 'nodes['+self.name+'].outputs[1].m_Value'
		bl_对象变换帧.f_数据插帧(self.id_data, path, 'F32变量值', context.scene.frame_current, self.m_Value, 0)

class C_NODE_MENU_FloatVar(bpy.types.Operator):
	bl_idname = 'node.node_var_float'
	bl_label = 'Float 变量'
	bl_options = {'REGISTER', 'UNDO'}

	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_Float变量', use_transform=True)
		return {'FINISHED'}









#def f_变量创建(self, context)


class C_Node_Curve标量(基类.C_Node_基类):
	bl_dname = 'bl_node_Curve变量'
	bl_label = 'Curve 标量'
	
	#m_Value = bpy.props.StringProperty()
	def init(self, context):
		super(C_Node_Curve标量, self).f_init(context)
		
		self.outputs.new('C_Socket_F32', name='var')

		bpy.context.scene[self.name] = 1.0
		self.f_toCPP()

	def f_toCPP(self):
		是否更新 = engineLib.flexCAPI.f_创建Curve标量节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		#if 是否更新 :
		#	f_update_变量值改变(self, None)

	def draw_buttons(self, context, layout):
		col = layout.column()
		col.prop(bpy.context.scene, '["%s"]' % self.name)
		#col.template_curve_mapping(self, "m_Value")

	def f_release(self):
		del bpy.context.scene[self.name]
	
class C_NODE_MENU_Curve标量(bpy.types.Operator):
	bl_idname = 'node.node_var_curve'
	bl_label = 'Curve 标量'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_Curve标量', use_transform=True)
		return {'FINISHED'}












def f_update_矢量变量值改变(self, context):
	data = tuple(self.m_Value)
	engineLib.flexCAPI.f_node_传入BL数据(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), ctypes.py_object(data));
	if context:
		self.id_data.f_节点数据更新_更新树([self])



class C_Node_Vec3变量(基类.C_Node_基类):
	bl_dname = 'bl_node_Vec3'
	bl_label = 'vec3 变量'
	
	m_Value = bpy.props.FloatVectorProperty(size=3, update=f_update_矢量变量值改变)
	def init(self, context):
		super(C_Node_Vec3变量, self).f_init(context)
		self.outputs.new('C_Socket_Vec3', name='var')
		self.f_toCPP()

	def f_toCPP(self):
		是否更新 = engineLib.flexCAPI.f_创建Vec3值节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		if 是否更新 :
			f_update_矢量变量值改变(self, None)

	def draw_buttons(self, context, layout):
		layout.prop(self, "m_Value")

class C_NODE_MENU_iVec3变量(bpy.types.Operator):
	bl_idname = 'node.node_var_ivec3'
	bl_label = 'ivec3 变量'
	bl_options = {'REGISTER', 'UNDO'}

	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_iVec3变量', use_transform=True)
		return {'FINISHED'}







class C_Node_iVec3变量(基类.C_Node_基类):
	bl_dname = 'bl_node_iVec3'
	bl_label = 'ivec3 变量'
	
	m_Value = bpy.props.IntVectorProperty(size=3, update=f_update_矢量变量值改变)
	def init(self, context):
		super(C_Node_iVec3变量, self).f_init(context)
		self.outputs.new('C_Socket_iVec3', name='var')
		self.f_toCPP()

	def f_toCPP(self):
		是否更新 = engineLib.flexCAPI.f_创建iVec3值节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		if 是否更新 :
			f_update_矢量变量值改变(self, None)
			
	def draw_buttons(self, context, layout):
		layout.prop(self, "m_Value")

class C_NODE_MENU_iVec3变量(bpy.types.Operator):
	bl_idname = 'node.node_var_ivec3'
	bl_label = 'ivec3 变量'
	bl_options = {'REGISTER', 'UNDO'}

	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_iVec3变量', use_transform=True)
		return {'FINISHED'}








'''class C_Node_F32变量_Array2D(基类.C_Node_基类):
	bl_dname = 'bl_node_Array2D_F32'
	bl_label = 'Array2D_F32'
	
	m_Value = bpy.props.IntVectorProperty(name='维度', default=(1,1), size=2, update=f_update_矢量变量值改变)
	def init(self, context):
		super(C_Node_F32变量_Array2D, self).f_init(context)
		self.outputs.new('C_Socket_F32_Array2D', name='var')
		self.f_toCPP()

	def f_toCPP(self):
		是否更新 = engineLib.flexCAPI.f_创建Array2D_F32变量节点(ctypes.c_wchar_p(self.id_data.name), ctypes.c_wchar_p(self.name), self.f_getPyObject());
		if 是否更新 :
			f_update_矢量变量值改变(self, None)

	def draw_buttons(self, context, layout):
		layout.prop(self, "m_Value")

class C_NODE_MENU_2D_F32Var(bpy.types.Operator):
	bl_idname = 'node.global_node_var_2d_f32'
	bl_label = '2D F32'
	bl_options = {'REGISTER', 'UNDO'}
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_Node_F32变量_Array2D', use_transform=True)
		return {'FINISHED'}
'''






classes = (
	C_OPS_NODE_插入帧,



	C_Node_Int变量,
	C_NODE_MENU_IntVar,

	C_Node_Float变量,
	C_NODE_MENU_FloatVar,


	C_Node_Curve标量,
	C_NODE_MENU_Curve标量,


	C_Node_iVec3变量,
	C_NODE_MENU_iVec3变量,

	#C_Node_F32变量_Array2D,
	#C_NODE_MENU_2D_F32Var,

	#C_SN_3FloatVar,
	#C_NODE_MENU_3FloatVar
)

def register():
	for c in classes:
		bpy.utils.register_class(c)
		

def unregister():
	for c in classes:
		bpy.utils.unregister_class(c)

